package com.briup.day08;

/**
 * @author 谭梦寻
 * @version 1.1
 */
public class Test01 {
    /*
       == equals 区别
       基本数据类型： 1==2 true == false 比较的数值 二进制代码是否相同
       引用数据类型： equals 比较的两个引用是否实质相同一个对象 比较地址值（哈希值）
       equals 只能比较引用类型 即对象
       如果equals没有被重写  就使用时Object类中提供的逻辑 比较两个引用的地址值是否相等
       如果equals被重写了 就是重写后的逻辑
     */
/*
    重写发生在子父类中
    重载发生在一个类中
    重写规则：为了覆盖(重写)父类的方法
        1 重写要求权限不能缩小 访问修饰符可以扩大 不能被缩小
            public>protected>default>private
        2 两个方法的方法名 参数列表完全相同
        3 要求返回值的返回类型可以相同也可以不同 一般相同
        4 方法抛出异常类型的范围可以被缩小 但是不能够被扩大
            一般情况下，子类进行方法重写时，最好方法的声明完全一致
   结论：子类继承父类，在调用方法的时候，如果子类中没用重写，那么调用
        从父类继承的方法，如果子类重写了这个方法，那么调用到子类重写的方
        法。（ 非常重要 ）
   特殊情况：
        注意1：父类中的静态方法（属于类方法）不能被子类重写
        static静态方法算不上重写，它是属于父类所独有的，只是书写格式上跟重写相似
        注意2：父类中的私有方法（未被继承,不能被继承）不能被子类重写

        多态前提：
            子类继承父类
            子类重写父类中的方法
            父类的引用指向子类对象
        注意：
            当调用属性时，编译和运行都看左边 --》属性也没有重写
            当调用非重写方法时，编译和运行都看左边
            当调用重写方法时，编译看左边 运行看右边
*/
    public static void main(String[] args) {
//        1 面向对象创建字符串对象 通过构造器创建对象
        String s = new String("abc");
        String s2 = new String("abc");
/*
        System.out.println(s.equals(s2));//true
        不是一个对象 但是是String类型 比较长度后比较内容 都满足也会返回true
*/
        System.out.println(s.equals(s2));//true String里面重写了Object中的equals方法
        System.out.println(s==s2);//false 两个引用是否指向同一个对象
        Integer i = new Integer(1);
        Integer i2 = new Integer(1);
        System.out.println(i.equals(i2));// true 同理于String

//        多态 父类型的引用 指向子类型对象 --> 看等号右边
//        隐式转换 大类型 = 小类型 long a = 1;
        SuperName superName = new SubName();
        superName.method();//son
        superName.method2();//Father2
        SuperName superName1 = new SuperName();
//        superName.method3(); //私有方法无法调用 也无法继承
//        superName.method4();//报错

        /*
        子类对象调用该方法 引用的类型是父类型
        如果是重写 编译看左边 运行看右边
        即：是否能通过编译 由父类决定 父类引用无法调用子类私有方法
            运行结果看子类
        如果不是重写 编译和运行都是看左边
         */

        SuperName b = new SubName();
        Object o = new SuperName();
        o = b;//隐式转换
        b = (SubName) o;//强制转换 等价于SuperName b = o = new SubName();
        String s1 = new String("abc");
//        s1 = (String) o;//编译没问题 运行报错 ClassCastException

/*
    instanceof
        对象类型的比较
        判断引用名实际指向的对象，其所属类型是否为右边的类型名，
        返回boolean类型结果
*/
        Object b2 = new SubName();
        System.out.println(b2 instanceof String); //false
        System.out.println(b2 instanceof SubName); //true
        System.out.println(b2 instanceof Object); //true
    }
}
class SuperName {
    public static void main(String[] args) {
        SuperName superName = new SubName();
        superName.method();//son
        superName.method2();//Father2
        SuperName superName1 = new SuperName();
        superName.method3(); //Father3
//        superName.method4();//报错
//        String s = new String("asd");
//        System.out.println(s == 12);
    }
    public void method() {
        System.out.println("Father");
    }
    public static void method2() {
        System.out.println("Father2");
    }
    private void method3() {
        System.out.println("Father3");
    }
}
class SubName extends SuperName{
    public void method() {
        System.out.println("Son");
    }
    public static void method2() {
        System.out.println("Son2");
    }
    private void method3() {
        System.out.println("Son3");
    }
    public void method4() {
        System.out.println("Son4");
    }
}
